import Taro, { 
  showToast,
  showLoading,
  hideLoading
} from '@tarojs/taro'
import { param2string } from '../utils/index'
import { baseUrl } from '../config'

const HTTP_STATUS = {
  SUCCESS: 200,
  NOT_FOUND: 404,
  BAD_GATEWAY: 502,
  FORBIDDEN: 403
}

export default {
  baseOptions(opts, method = 'GET') {
    new Promise((resolve, reject) => {
      const { 
        url, 
        params={}, 
        data,
        through=false, // 错误返回
        loading=false, 
        loadingText='加载中',
        contentType='application/json' 
      } = opts
      
      const body = {
        ...data,
        timestamp: new Date().getTime()
      }

      const querystring = param2string({
        ...params, 
        token: Taro.getStorageSync('token') || ''
      })
  
      const option = {
        url: `${baseUrl}${url}${querystring ? `?${querystring}` : ''}`,
        data: body,
        method: method,
        header: {
          'content-type': contentType,
        },
        xhrFields: { withCredentials: true },
        success(res) {
          if (res.statusCode === HTTP_STATUS.SUCCESS) {
            if (loading) {
              hideLoading()
            }
            resolve(res.data)
          } else {
            if (res.statusCode === 403) {
              Taro.removeStorageSync('token')
              Taro.removeStorageSync('user')
              Taro.removeStorageSync('userType')
              Taro.reLaunch({
                url: '/pages/login/index'
              })
            }
            const statusMap = {
              404: '请求资源不存在',
              502: '服务端出现了问题',
              403: '登录已过期' // '没有权限访问'
            }
            const errorMsg = statusMap[res.statusCode] || '请求异常'
            if (!through) {
              setTimeout(() => {
                showToast({
                  title: errorMsg,
                  mask: true,
                  icon: 'none',
                  duration: 2000
                })
              }, 301)
            }
            requestTask.abort()
          }
        },
        fail() {
          if (loading) {
            hideLoading()
          }
          reject()
        }
      }
      if (loading) {
        showLoading({
          title: loadingText,
          mask: true,
        })
      }
      const requestTask = wx.request(option)
    })
  },
  get(option) {
    return this.baseOptions(option, 'GET')
  },
  post(option) {
    return this.baseOptions(option, 'POST')
  },
  put(option) {
    return this.baseOptions(option, 'PUT')
  },
  delete(option) {
    return this.baseOptions(option, 'DELETE')
  }
}
